"""
鼠标交互模块
负责处理鼠标悬停显示信息等功能
"""

import pyqtgraph as pg
from typing import Optional, Callable, Dict, Any
from .data_loader import DataLoader


class MouseInteraction:
    """鼠标交互管理类"""
    
    def __init__(self, plot_widget: pg.PlotWidget, data_loader: DataLoader,
                 chart_type: str = "kline"):
        """
        初始化鼠标交互
        
        Args:
            plot_widget: PyQtGraph绘图控件
            data_loader: 数据加载器实例
            chart_type: 图表类型 ("kline" 或 "volume")
        """
        self.plot_widget = plot_widget
        self.data_loader = data_loader
        self.chart_type = chart_type
        self.info_text: Optional[pg.TextItem] = None
        self.proxy: Optional[pg.SignalProxy] = None
        self.plot_widget.enableAutoRange(axis=pg.ViewBox.YAxis, enable=False)   # 禁用Y轴自动范围调整
        
        # 创建信息显示文本
        self._create_info_text()
        
        # 连接鼠标事件
        self._connect_mouse_events()
    
    def _create_info_text(self):
        """创建信息显示文本"""
        self.info_text = pg.TextItem(
            anchor=(0, 0), 
            color='w', 
            fill=pg.mkColor(0, 0, 0, 200)
        )

        self.plot_widget.addItem(self.info_text)
        # self.plot_widget.getViewBox().scene().addItem(self.info_text)
        self.info_text.hide()
        self.info_text.setZValue(100)  # 设置最高层级
    
    def _connect_mouse_events(self):
        """连接鼠标事件"""
        self.proxy = pg.SignalProxy(
            self.plot_widget.scene().sigMouseMoved, 
            rateLimit=60, 
            slot=self._on_mouse_move
        )
    
    def _on_mouse_move(self, signal):
        """鼠标移动事件处理"""
        try:
            self.plot_widget.enableAutoRange(axis=pg.ViewBox.YAxis, enable=False)   # 禁用Y轴自动范围调整
            pos = self.plot_widget.vb.mapSceneToView(signal[0])
            x_pos = int(round(pos.x()))
            
            # 获取数据
            data = self.data_loader.get_data_by_index(x_pos)
            
            if data is not None:
                # 生成信息文本
                info = self._generate_info_text(data)
                
                self.info_text.setText(info)
                self.info_text.setPos(pos.x(), pos.y())
                self.info_text.show()
            else:
                self.info_text.hide()
                
        except Exception as e:
            print(f"{self.chart_type}图表鼠标事件错误: {e}")
            self.info_text.hide()
    
    def _generate_info_text(self, data: Dict[str, Any]) -> str:
        """
        生成信息文本
        
        Args:
            data: 数据字典
            
        Returns:
            格式化的信息文本
        """
        if self.chart_type == "kline":
            return self._generate_kline_info(data)
        elif self.chart_type == "volume":
            return self._generate_volume_info(data)
        else:
            return ""
    
    def _generate_kline_info(self, data: Dict[str, Any]) -> str:
        """生成K线图信息文本"""
        return f"""日期: {data['date'].strftime('%Y-%m-%d')}
开盘: {data['open']:.2f}
最高: {data['high']:.2f}
最低: {data['low']:.2f}
收盘: {data['close']:.2f}
涨跌: {data['change']:.2f}
涨跌幅: {data['pct_change']:.2f}%"""
    
    def _generate_volume_info(self, data: Dict[str, Any]) -> str:
        """生成成交量图信息文本"""
        return f"""日期: {data['date'].strftime('%Y-%m-%d')}
成交量: {data['vol']:,} 手
成交额: {data['amount']:,.0f} 元"""
    
    def disconnect(self):
        """断开鼠标事件连接"""
        if self.proxy is not None:
            try:
                self.plot_widget.scene().sigMouseMoved.disconnect(self.proxy)
            except:
                pass
            self.proxy = None
    
    def __del__(self):
        """析构函数，确保断开连接"""
        self.disconnect()


class MouseInteractionManager:
    """鼠标交互管理器，管理多个图表的鼠标交互"""
    
    def __init__(self):
        self.interactions: list = []
    
    def add_interaction(self, interaction: MouseInteraction):
        """
        添加鼠标交互
        
        Args:
            interaction: 鼠标交互实例
        """
        self.interactions.append(interaction)
    
    def remove_interaction(self, interaction: MouseInteraction):
        """
        移除鼠标交互
        
        Args:
            interaction: 要移除的鼠标交互实例
        """
        if interaction in self.interactions:
            interaction.disconnect()
            self.interactions.remove(interaction)
    
    def disconnect_all(self):
        """断开所有鼠标交互"""
        for interaction in self.interactions:
            interaction.disconnect()
        self.interactions.clear()
    
    def __del__(self):
        """析构函数"""
        self.disconnect_all()
